module MODULATION_FM
(
    input clk_in_50m,
    input rst_n_in,
    input fre_offset_mode,
    input [31:0] carrier_freword_in,
    
    output reg [13:0] modulation_FM_result,
    output clk_out_100m
);

/* parameter define */
parameter MODULATION_FREWORD = 32'd42950;//1kHz
parameter freoffset_freword_5k = 32'd214748*2;
parameter freoffset_freword_10k = 32'd429497*2;
parameter A = 14'd8191;

/* wire define */
wire clk_100m;
wire pll_locked;
wire rst_n;
wire signed [13:0] signal_modulator;
wire signed [45:0] mult_result;
wire [31:0] freoffset_freword_MAX;
wire [31:0] freoffset_freword;
wire [11:0] rom_addr;
wire [13:0] modulation_FM_result_signed;

/* reg define */
reg [31:0] addr;

assign rst_n = pll_locked & rst_n_in;
assign clk_out_100m = clk_100m;

/* mux21 choose freword */
MUX21	MUX21_inst (
	.data0x ( freoffset_freword_5k ),
	.data1x ( freoffset_freword_10k ),
	.sel ( fre_offset_mode ),
	.result ( freoffset_freword_MAX )
	);

MULT	MULT_inst (
	.dataa ( freoffset_freword_MAX ),
	.datab ( signal_modulator ),
	.result ( mult_result )
	);

assign freoffset_freword = mult_result[45:14];

always @(posedge clk_100m or negedge rst_n)
begin
    if(rst_n == 0)
    begin
        addr <= 32'd0;
    end
    else
    begin
        addr <= addr + carrier_freword_in + freoffset_freword;
    end
end

assign rom_addr[11:0] = addr[31:20];

PLL	PLL_inst (
	.inclk0 ( clk_in_50m ),
	.c0 ( clk_100m ),
	.locked ( pll_locked )
	);

DDS_sin DDS_sin_modulator (
	.clk_in_100m(clk_100m),
	.rst_n(rst_n),
	.fre_word_in(MODULATION_FREWORD),
	.dacdata(signal_modulator)
);

ROM_sin	ROM_sin_inst (
	.address ( rom_addr ),
	.clock ( clk_100m ),
	.q ( modulation_FM_result_signed )
	);

always @(posedge clk_100m)
begin
	modulation_FM_result <= modulation_FM_result_signed + A;
end
	
endmodule
